home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 5
/
Aminet 5 - March 1995.iso
/
Aminet
/
mus
/
edit
/
AlgoRhythms.lha
/
AlgoRhythms
/
Source
/
pitchnames.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-11-25
|
5KB
|
184 lines
/* pitchnames.c
Copyright (c) 1993 by Thomas E. Janzen
All Rights Reserved
THIS SOFTWARE IS FURNISHED FREE OF CHARGE FOR STUDY AND USE AND MAY
BE COPIED ONLY FOR PERSONAL USE OR COMPLETELY AS OFFERED WITH NO
CHANGES FOR FREE DISTRIBUTION. NO TITLE TO AND OWNERSHIP OF THE
SOFTWARE IS HEREBY TRANSFERRED. THOMAS E. JANZEN ASSUMES NO
RESPONSIBILITY FOR THE USE OR RELIABILITY OF THIS SOFTWARE.
Thomas E. Janzen
208A Olde Derby Road
Norwood, MA 02062-1761
(617)769-7733
** FACILITY:
**
** AlgoRhythms music improviser on Commodore (TM) Amiga (TM)
** compiled with SAS/C Amiga Compiler 6.50
**
** ABSTRACT:
**
** pitchnames.c inter-converts pitch name strings and MIDI note numbers
**
** AUTHORS: Thomas E. Janzen
**
** CREATION DATE: 26-OCT-1993
**
** MODIFICATION HISTORY:
** DATE NAME DESCRIPTION
**--
*/
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <stdio.h>
#include "pitchnames.h"
#define C_HAS_ACCIDENTAL (3)
#define C_NO_ACCIDENTAL (2)
#define C_SMALL_SCALE_LEN (7)
#define C_NOTES_PER_OCTAVE (12)
#define C_A (9)
#define C_B (11)
#define C_C (0)
#define C_D (2)
#define C_E (4)
#define C_F (5)
#define C_G (7)
int pitch_to_midi(const char *pitch_name)
/*
** FUNCTIONAL DESCRIPTION:
** Converts a pitch name string to the represented MIDI note number
** ("C4" is middle C is MIDI 60; "C#4" is c-sharp above middle c (61);
** "Cb4" and "CB4" are the C-flat (B) below middle C (59).)
** If pitch_name was invalid, a zero is returned.
**
** RETURN VALUE:
** description: MIDI note number
** data_type: int
**
** ARGUMENTS:
**
** pitch_name-
** description: name of pitch, e.g. C4, D#2, Gb6
** data_type: pointer char
** access: read only
**
** DESIGN:
** ROUTINE
** : put length of input string into pitch_name_len
** : pitch_name_letter = toupper(force pitch_name[0])
** : IF pitch_name[0] is A..G, or pitch_name length is 2 or 3
** : THEN
** : : pitch_midi = small_scale[pitch_name_letter - 'A']
** : : IF (pitch_name_len == C_HAS_ACCIDENTAL)
** : : : SELECT toupper(pitch_name[1])
** : : : : CASE 'B'
** : : : : : lower pitch_midi by 1
** : : : : CASE '#'
** : : : : : raise pitch_midi by 1
** : : : ENDSELECT
** : : : octave = strtol(pitch_name[pitch_name_len - 1])
** : : : pitch_midi = pitch_midi + (C_NOTES_PER_OCTAVE * (octave + 1));
** : ELSE
** : : pitch_midi = 0
** : ENDIF
** : return pitch_midi
** ENDROUTINE
*/
{
auto int pitch_midi,
pitch_name_len,
octave,
pitch_name_letter;
const static int small_scale[C_SMALL_SCALE_LEN]
= {C_A, C_B, C_C, C_D, C_E, C_F, C_G};
/*
** Pre-compute the string length
** and force pitch_name[0] to uppercase and put into pitch_name_letter
*/
pitch_name_len = strlen(pitch_name);
pitch_name_letter = toupper(pitch_name[0]);
if ( (pitch_name_letter >= 'A')
|| (pitch_name_letter <= 'G')
|| (pitch_name_len <= C_HAS_ACCIDENTAL)
|| (pitch_name_len >= C_NO_ACCIDENTAL)
)
{
/*
** find the pre-accidental pitch number (A..G natural)
*/
pitch_midi = small_scale[pitch_name_letter - 'A'];
if (C_HAS_ACCIDENTAL == pitch_name_len)
{
/*
** If there is an accidental (sharp # or flat b)
** then adjust the pitch up or down a semitone
*/
switch (toupper(pitch_name[1]))
{
case 'B': /* a flat */
pitch_midi -= 1;
break;
case '#':
pitch_midi += 1; /* a sharp */
break;
default:
break;
}
}
/*
** Extract the octave from the input string
*/
octave = strtol(&(pitch_name[pitch_name_len - 1]), NULL, 10);
/*
** Computer the MIDI pitch number
*/
pitch_midi += (C_NOTES_PER_OCTAVE * (octave + 1));
}
else
{
/*
** input string was bad data, so return a zero.
*/
pitch_midi = 0;
}
return pitch_midi;
}
void midi_to_pitch(const int note_num, char *pitch_name)
/*
** FUNCTIONAL DESCRIPTION:
**
** ARGUMENTS:
**
** note_num-
** description: MIDI note number
** data_type: int
** access: read only
**
** pitch_name-
** description: string of pitch name e.g. C#4, D#2, F1, E6
** data_type: pointer to char
** access: write only
**
** DESIGN:
*/
{
/* convert MIDI note numbers to pitch name string */
/* C4 is middle C is MIDI 60 */
const char note_names[12][4] =
{"C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"};
sprintf(pitch_name, "%s%1d", note_names[note_num % 12],
(note_num / 12) - 1);
return;
}